﻿using System;
using System.Collections.Generic;
using AccessControl.Contracts.Settings;
using AccessControl.Contracts.Models;
using System.Collections.ObjectModel;
using AccessControl.DataManagers;
using AccessControl.Gateway.Managers;

namespace AccessControl.Gateway.Settings
{
	class CamerasSettings : ICamerasSettings
	{
		#region Fields

		private static CamerasSettings s_Instance = null;
		private ObservableCollection<ICamera> _Items = new ObservableCollection<ICamera>();


		#endregion

		#region Private Constructor

		/// <summary>
		/// Initializes a new instance of the <see cref="T:System.Object"/> class.
		/// </summary>
		/// <remarks></remarks>
		private CamerasSettings()
		{
			DataManager.Instance.FillList(Items);
		}

		#endregion

		#region Public Properties

		/// <summary>
		/// Gets the instace.
		/// </summary>
		/// <remarks></remarks>
		public static CamerasSettings Instance
		{
			get 
			{
				lock (typeof(CamerasSettings))
				{
					if (s_Instance == null)
						s_Instance = new CamerasSettings();

					return s_Instance;
				}
			}
		}

		#endregion
		
		#region ICamerasSettings Members

		public bool Add(ICamera item)
		{
			if (DataManager.Instance.Add(item))
			{
				/* Add it to the matching entry in the entries manager */
				foreach (IEntry entry in EntriesManager.Instance.Items)
				{
					/* If the same one */
					if (entry.Id == item.RelatedEntryId)
					{
						/* Add it */
						entry.Cameras.Add(item);
						break;
					}
				}

				/* And to the maps manager */
				foreach (IMap map in MapsManager.Instance.Items)
				{
					foreach (IMapEntry mapEntry in map.Entries)
					{
						/* If the same one */
						if (mapEntry.Id == item.RelatedEntryId)
						{
							/* Add it */
							mapEntry.Cameras.Add(item);
							break;
						}
					}
				}

				return true;
			}

			return false;
		}

		public bool Update(ICamera item)
		{

			if (DataManager.Instance.Update(item))
			{
				foreach (IEntry entry in EntriesManager.Instance.Items)
				{
					/* If the same one */
					if (entry.Id == item.RelatedEntryId)
					{
						/* Find that camera */
						for (int i = 0; i < entry.Cameras.Count; ++i)
						{
							if (entry.Cameras[i].Id == item.Id)
							{
								/* Update */
								entry.Cameras.RemoveAt(i);
								entry.Cameras.Insert(i, item);
								break;
							}
						}

					}
				}

				/* And to the maps manager */
				foreach (IMap map in MapsManager.Instance.Items)
				{
					foreach (IMapEntry mapEntry in map.Entries)
					{
						/* If the same one */
						if (mapEntry.Id == item.RelatedEntryId)
						{
							/* Find that camera */
							for (int i = 0; i < mapEntry.Cameras.Count; ++i)
							{
								if (mapEntry.Cameras[i].Id == item.Id)
								{
									/* Update */
									mapEntry.Cameras.RemoveAt(i);
									mapEntry.Cameras.Insert(i, item);
									break;
								}
							}
						}
					}
				}

				return true;
			}

			return false;
		}

		public bool Delete(ICamera item)
		{
			if (DataManager.Instance.Delete(item))
			{
				/* Go over the entries */
				foreach (IEntry entry in EntriesManager.Instance.Items)
				{
					/* If the same one */
					if (entry.Id == item.RelatedEntryId)
					{
						/* Find that camera */
						for (int i = 0; i < entry.Cameras.Count; ++i)
						{
							if (entry.Cameras[i].Id == item.Id)
							{
								/* Update */
								entry.Cameras.RemoveAt(i);
								break;
							}
						}

					}
				}

				/* And to the maps manager */
				foreach (IMap map in MapsManager.Instance.Items)
				{
					foreach (IMapEntry mapEntry in map.Entries)
					{
						/* If the same one */
						if (mapEntry.Id == item.RelatedEntryId)
						{
							/* Find that camera */
							for (int i = 0; i < mapEntry.Cameras.Count; ++i)
							{
								if (mapEntry.Cameras[i].Id == item.Id)
								{
									/* Update */
									mapEntry.Cameras.RemoveAt(i);
									break;
								}
							}
						}
					}
				}

				return true;
			}

			return false;
		}

		public IList<ICamera> Items
		{
			get { return _Items; }
		}

		public void Load()
		{
			Items.Clear();
			DataManager.Instance.FillList(Items);
		}

		#endregion
	}
}
